package com.jmz.apt.api.Utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

/**
 * Created by fanglexue on 2019/10/25.
 */
@Slf4j
public class JsonSerializerUtil {

        private static ObjectMapper mapper;

        static {
            mapper=new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            //mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
            mapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, true);
            mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, true);
        }

        public static <T> String obj2String(T obj){
            if(obj == null){
                return null;
            }
            try {
                return obj instanceof String ? (String)obj :  mapper.writeValueAsString(obj);
            } catch (Exception e) {
                log.warn("Parse Object to String error",e);
                return null;
            }
        }
        public static <T> String obj2StringPretty(T obj){
            if(obj == null){
                return null;
            }
            try {
                return obj instanceof String ? (String)obj :  mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
            } catch (Exception e) {
                log.warn("Parse Object to String error",e);
                return null;
            }
        }
        public static <T> T string2Obj(String str,Class<T> clazz){
            if(StringUtils.isEmpty(str) || clazz == null){
                return null;
            }

            try {
                return clazz.equals(String.class)? (T)str : mapper.readValue(str,clazz);
            } catch (Exception e) {
                log.warn("Parse String to Object error",e);
                return null;
            }
        }
        public static <T> T string2Obj(String str, TypeReference<T> typeReference){
            if(StringUtils.isEmpty(str) || typeReference == null){
                return null;
            }
            try {
                return (T)(typeReference.getType().equals(String.class)? str : mapper.readValue(str,typeReference));
            } catch (Exception e) {
                log.warn("Parse String to Object error",e);
                return null;
            }
        }

        public static <T> T string2Obj(String str,Class<?> collectionClass,Class<?>... elementClasses){
            JavaType javaType = mapper.getTypeFactory().constructParametricType(collectionClass,elementClasses);
            try {
                return mapper.readValue(str,javaType);
            } catch (Exception e) {
                log.warn("Parse String to Object error",e);
                return null;
            }
        }
}
